<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class AccessLog extends Model
{
    protected $fillable = [
        'user_id',
        'user_name',
        'user_ip',
        'user_agent',
        'session_id',
        'method',
        'url',
        'route_name',
        'controller_action',
        'query_string',
        'request_data',
        'response_code',
        'response_size',
        'response_time',
        'access_type',
        'module_name',
        'action_name',
        'device_type',
        'browser',
        'browser_version',
        'os',
        'country',
        'city',
        'is_suspicious',
        'suspicious_reason',
        'security_flags',
        'memory_usage',
        'db_queries_count',
        'db_queries_time',
        'related_model',
        'related_id',
        'metadata',
        'notes'
    ];

    protected $casts = [
        'request_data' => 'array',
        'response_time' => 'decimal:3',
        'db_queries_time' => 'decimal:3',
        'is_suspicious' => 'boolean',
        'security_flags' => 'array',
        'metadata' => 'array',
    ];

    // 访问类型常量
    const ACCESS_TYPE_API = 'api';
    const ACCESS_TYPE_PAGE = 'page';
    const ACCESS_TYPE_FILE = 'file';
    const ACCESS_TYPE_STATIC = 'static';

    // 设备类型常量
    const DEVICE_DESKTOP = 'desktop';
    const DEVICE_MOBILE = 'mobile';
    const DEVICE_TABLET = 'tablet';

    /**
     * 获取关联用户
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * 获取响应状态码标签
     */
    public function getResponseCodeLabelAttribute(): string
    {
        return match(true) {
            $this->response_code >= 200 && $this->response_code < 300 => '成功',
            $this->response_code >= 300 && $this->response_code < 400 => '重定向',
            $this->response_code >= 400 && $this->response_code < 500 => '客户端错误',
            $this->response_code >= 500 => '服务器错误',
            default => '未知'
        };
    }

    /**
     * 获取访问类型标签
     */
    public function getAccessTypeLabelAttribute(): string
    {
        return match($this->access_type) {
            self::ACCESS_TYPE_API => 'API接口',
            self::ACCESS_TYPE_PAGE => '页面访问',
            self::ACCESS_TYPE_FILE => '文件访问',
            self::ACCESS_TYPE_STATIC => '静态资源',
            default => '未知'
        };
    }

    /**
     * 获取设备类型标签
     */
    public function getDeviceTypeLabelAttribute(): string
    {
        return match($this->device_type) {
            self::DEVICE_DESKTOP => '桌面设备',
            self::DEVICE_MOBILE => '移动设备',
            self::DEVICE_TABLET => '平板设备',
            default => '未知设备'
        };
    }

    /**
     * 获取响应时间格式化字符串
     */
    public function getResponseTimeFormattedAttribute(): string
    {
        if (!$this->response_time) {
            return '-';
        }

        if ($this->response_time < 1) {
            return round($this->response_time * 1000, 2) . 'ms';
        }

        return round($this->response_time, 2) . 's';
    }

    /**
     * 检查是否为可疑访问
     */
    public function isSuspiciousAccess(): bool
    {
        return $this->is_suspicious;
    }

    /**
     * 范围查询：按用户筛选
     */
    public function scopeByUser($query, int $userId)
    {
        return $query->where('user_id', $userId);
    }

    /**
     * 范围查询：按访问类型筛选
     */
    public function scopeByAccessType($query, string $accessType)
    {
        return $query->where('access_type', $accessType);
    }

    /**
     * 范围查询：按响应状态码筛选
     */
    public function scopeByResponseCode($query, int $responseCode)
    {
        return $query->where('response_code', $responseCode);
    }

    /**
     * 范围查询：按模块筛选
     */
    public function scopeByModule($query, string $moduleName)
    {
        return $query->where('module_name', $moduleName);
    }

    /**
     * 范围查询：按时间范围筛选
     */
    public function scopeByDateRange($query, string $startDate, string $endDate)
    {
        return $query->whereBetween('created_at', [$startDate, $endDate]);
    }

    /**
     * 范围查询：获取可疑访问
     */
    public function scopeSuspicious($query)
    {
        return $query->where('is_suspicious', true);
    }

    /**
     * 范围查询：按响应时间筛选（慢查询）
     */
    public function scopeSlowRequests($query, float $threshold = 1.0)
    {
        return $query->where('response_time', '>', $threshold);
    }

    /**
     * 统计访问量
     */
    public static function getAccessStats(string $startDate = null, string $endDate = null): array
    {
        $query = self::query();

        if ($startDate && $endDate) {
            $query->whereBetween('created_at', [$startDate, $endDate]);
        }

        return [
            'total_requests' => $query->count(),
            'successful_requests' => (clone $query)->whereBetween('response_code', [200, 299])->count(),
            'error_requests' => (clone $query)->where('response_code', '>=', 400)->count(),
            'avg_response_time' => (clone $query)->avg('response_time'),
            'unique_users' => (clone $query)->distinct('user_id')->count('user_id'),
            'unique_ips' => (clone $query)->distinct('user_ip')->count('user_ip'),
        ];
    }
}
